function qvTrace(varargin)
% qvTrace
%
% Use this to look at nimex ephus xsg traces.
%   Derived from quickViewTrace.
%
% Notes:
%   Data are available as 'currentTrace' variable in the workspace

% TODO:

% editing:
% gs dec 2007 -- Cloned from quickViewTrace and modified
%% ------- switchyard ----------------
if nargin == 0
    mode = 'init';
else
    mode = varargin{1};
end

% preferred default directory
defaultDirectory = 'C:\_Data';

switch mode
    case 'init'
        % select a trace to open
        try
            cd(defaultDirectory);
        catch
            try
                cd('C:\Data');
            catch
%                 disp('qvTrace: unable to find default dir.')
            end
        end
        [filename, pathname] = uigetfile('*.xsg', 'Select an XSG trace');
        % if filename == 0 | pathname == 0
        if isequal(filename,0)|| isequal(pathname,0)
            return
        end
        fullfilename = fullfile(pathname, filename);
        [pathstr, tracename, ext, versn] = fileparts(fullfilename);
        data.completename = fullfile(pathstr, [tracename, ext, versn]);

        hfig = figure(1000);
        %         data = get(gcf, 'UserData');
        % store the file and directory info
        set(hfig, 'UserData', data.completename);

        %         clf;
        % figure
        set(hfig, 'Color', 'w', 'Name', 'qvTrace', ...
            'NumberTitle', 'off', ...
            'Position', [360    55   560   657]);

    case 'select new file'
        hfig = figure(1000);
        data = get(gcf, 'UserData');
        saveCurrentDirectory = pwd;
        [pathstr, tracename, ext, versn] = fileparts(data.completename);
        cd(pathstr);
        % select a trace to open
        [filename, pathname] = uigetfile('*.xsg', 'Select an XSG trace');
        % if filename == 0 | pathname == 0
        if isequal(filename,0)|isequal(pathname,0)
            return
        end
        fullfilename = fullfile(pathname, filename);
        [pathstr, tracename, ext, versn] = fileparts(fullfilename);
        data.completename = fullfile(pathstr, [tracename, ext, versn]);
        cd(saveCurrentDirectory)

        % figure
        hfig = figure(1000);
%         data = get(gcf, 'UserData');
        clf;
%         set(hfig, 'Color', 'w', 'Name', 'qvTrace', ...
%             'NumberTitle', 'off', ...
%             'Position', [360    55   560   657]);
        % store the file and directory info
        set(hfig, 'UserData', data.completename);

    case 'scroll backwards'
        hfig = figure(1000);
        data = get(gcf, 'UserData');
        clf;
%         set(hfig, 'Color', 'w', 'Name', 'qvTrace', ...
%             'NumberTitle', 'off', ...
%             'Position', [360    55   560   657]);
        [pathstr, tracename, ext, versn] = fileparts(data.completename);
        fullfile(pathstr, ['*' ext]);
        traceFiles = dir(fullfile(pathstr, ['*' ext]));
        c = struct2cell(traceFiles);
        list = char(c{1,:});
        k = strmatch(tracename, list);
        if k > 1
            newfilename = list(k-1,:); % file name of the preceding (k-1) file
            data.completename = fullfile(pathstr, newfilename);
            [pathstr, tracename, ext, versn] = fileparts(data.completename);
        end

        % store the file and directory info
        set(hfig, 'UserData', data);

    case 'scroll forwards'
        hfig = figure(1000);
        data = get(gcf, 'UserData');
        clf;
%         set(hfig, 'Color', 'w', 'Name', 'qvTrace', ...
%             'NumberTitle', 'off', ...
%             'Position', [360    55   560   657]);
        [pathstr, tracename, ext, versn] = fileparts(data.completename);
        fullfile(pathstr, ['*' ext]);
        traceFiles = dir(fullfile(pathstr, ['*' ext]));
        c = struct2cell(traceFiles);
        list = char(c{1,:});
        k = strmatch(tracename, list);
        if k < size(list, 1)
            newfilename = list(k+1,:); % file name of the following (k+1) file
            data.completename = fullfile(pathstr, newfilename);
            [pathstr, tracename, ext, versn] = fileparts(data.completename);
        end

        % store the file and directory info
        set(hfig, 'UserData', data);

%     case 'header to command line'
%         hfig = figure(1000);
%         data = get(gcf, 'UserData');
%         eval('data.currentTrace.header.ephys.ephys');
%         return
end
%% open the file, extract the data
currentTrace = load(data.completename, '-mat');

% put the data in the workspace
assignin('base', 'currentTrace', currentTrace);

% store in figure's userData
data.currentTrace = currentTrace;
set(hfig, 'UserData', data);

% TODO: fix this temporary KLUGE
if ~isfield(currentTrace.header.acquirer.acquirer, 'acqOnArray')
    currentTrace.header.acquirer.acquirer.acqOnArray = 0;
end

%% determine what was acq'd and stim'd, and how
NacqEphys = currentTrace.header.ephys.ephys.startButton * ...
    sum(currentTrace.header.ephys.ephys.acqOnArray);
Nother = currentTrace.header.ephys.ephys.startButton * ...
    sum(currentTrace.header.ephys.ephys.stimOnArray) + ...
    currentTrace.header.acquirer.acquirer.startButton * ...
    sum(currentTrace.header.acquirer.acquirer.acqOnArray) + ...
    currentTrace.header.stimulator.stimulator.startButton * ...
    sum(currentTrace.header.stimulator.stimulator.stimOnArray);

% decide subplot layout
Nsub = 2 * NacqEphys + Nother; % ephys traces count double
plotnum = 0;

% were data obtained by pulseJacker? (If so, different method for determining pulses)
pulseJackerFlag = currentTrace.header.pulseJacker.pulseJacker.enable; 
if pulseJackerFlag; 
    disp(' '); 
    disp('pulseJacker trace'); 
end

% who triggered whom:
disp(' ');
disp(['ephys startButton: ' num2str(currentTrace.header.ephys.ephys.startButton)]);
disp(['acq startButton: ' num2str(currentTrace.header.acquirer.acquirer.startButton)]);
disp(['stim startButton: ' num2str(currentTrace.header.stimulator.stimulator.startButton)]);
disp(['ephys externalTrigger: ' num2str(currentTrace.header.ephys.ephys.externalTrigger)]);
disp(['acq externalTrigger: ' num2str(currentTrace.header.acquirer.acquirer.externalTrigger)]);
disp(['stim externalTrigger: ' num2str(currentTrace.header.stimulator.stimulator.externalTrigger)]);

% loop??: yes, if selfTrigger=0 for all started programs (startButton=1)
loopFlag = 0;
loopDaqFlag = 0;
loopCpuFlag = 0;
loopIterations = currentTrace.header.loopGui.loopGui.iterations;
loopIterationCounter = currentTrace.header.loopGui.loopGui.iterationCounter;
numberOfSelfTriggeringPrograms = currentTrace.header.ephys.ephys.startButton * currentTrace.header.ephys.ephys.selfTrigger + ...
currentTrace.header.acquirer.acquirer.startButton * currentTrace.header.acquirer.acquirer.selfTrigger + ...
currentTrace.header.stimulator.stimulator.startButton * currentTrace.header.stimulator.stimulator.selfTrigger;
if numberOfSelfTriggeringPrograms == 0
    loopFlag = 1;
    if currentTrace.header.loopGui.loopGui.cpuTiming
        loopCpuFlag = 1; 
        loopDaqFlag = 0;
    else
        loopCpuFlag = 0; 
        loopDaqFlag = 1;
    end
    loopIterations = currentTrace.header.loopGui.loopGui.iterations;
end
disp(['loopFlag: ' num2str(loopFlag) '; loopCpuFlag: ' num2str(loopCpuFlag) '; loopDaqFlag: ' num2str(loopDaqFlag) ...
    '; iterations: ' num2str(loopIterations) '; counter: ' num2str(loopIterationCounter)]);

%% ============ EPHYS TRACE, CHANNEL 1 ==================
% TODO: plot multiple channels using FOR loop
if currentTrace.header.ephys.ephys.startButton && currentTrace.header.ephys.ephys.acqOnArray(1) == 1;
    ephysdata = currentTrace.data.ephys.trace_1;
    timedata = 0 : size(ephysdata, 1) - 1;
    timedata = timedata / currentTrace.header.ephys.ephys.sampleRate;
    plotnum = plotnum + 1;
    hsub = subplot(Nsub, 1, [plotnum plotnum+1]);
    plotnum = plotnum + 1; % double-high subplot for ephys traces
    hplot = plot(timedata, ephysdata);
    xlabel('Time (seconds)');
    ylabel('Amplitude');
    traceType = '';
    if loopFlag
        if loopCpuFlag
        traceType = [' -- cpu loop, iteration ' num2str(loopIterationCounter) ' of ' num2str(loopIterations)];
        elseif loopDaqFlag
            traceType = [' -- daq loop, all ' num2str(loopIterations) ' iterations'];
        end
    end
    htitle = title([pathstr '\' tracename traceType]);
    set(htitle, 'Interpreter', 'none');
    box off;
end

%% plot corresponding ephys stim pulse
% TODO: determine timedata here, instead of relying on the above
if currentTrace.header.ephys.ephys.startButton && currentTrace.header.ephys.ephys.stimOnArray(1) == 1;
    try % TODO: get rid of the try 
        traceLength = currentTrace.header.ephys.ephys.traceLength;
        if ~pulseJackerFlag
            params = currentTrace.header.ephys.ephys.pulseParameters{:};
        else
            % TODO: check this stuff ...
            cp = currentTrace.header.pulseJacker.pulseJacker.currentPosition;
            np = size(currentTrace.header.pulseJacker.pulseJacker.positions{1}, 2);
            params = currentTrace.header.pulseJacker.pulseJacker.pulseDataMap{(cp-1)*np+1}(:);
        end
        pulseTrace = pulseTraceFromParameters(params, traceLength);
        timedata = ((0 : currentTrace.header.ephys.ephys.sampleRate * currentTrace.header.ephys.ephys.traceLength - 1) / ...
            currentTrace.header.ephys.ephys.sampleRate)';
        if loopFlag && loopDaqFlag
            pulseTrace = repmat(pulseTrace, loopIterations, 1);
            timedata = ((0 : currentTrace.header.ephys.ephys.sampleRate * currentTrace.header.ephys.ephys.traceLength ...
                * loopIterations - 1) / currentTrace.header.ephys.ephys.sampleRate)';
        end
        plotnum = plotnum + 1;
        hsub = subplot(Nsub, 1, plotnum);
        hplot = plot(timedata, pulseTrace);
        set(hplot, 'LineWidth', 2, 'Color', 'r');
        xlabel('Time (seconds)');
        ylabel('Amplitude');
        htitle = title(['Pulse: ' params.name]);
        set(htitle, 'Interpreter', 'none');
        box off;
    catch
        disp('qvTrace: problem making ephys stim pulse.')
    end
end

% %% ============ ACQUIRER TRACE(S) ==================
% % TODO: plot multiple acquirer traces using FOR loop
% if currentTrace.header.acquirer.acquirer.startButton && ...
%         currentTrace.header.acquirer.acquirer.acqOnArray(1) == 1;
%     acquirerdata = currentTrace.data.acquirer.trace_1;
%     timedata = 0 : size(acquirerdata, 1) - 1;
%     sr = currentTrace.header.acquirer.acquirer.sampleRate;
%     timedata = timedata / sr;
%     plotnum = plotnum + 1;
%     hsub = subplot(Nsub, 1, plotnum);
%     hplot = plot(timedata, acquirerdata);
%     xlabel('Time (seconds)');
%     ylabel('Amplitude');
% %     htitle = title([pathstr '\' tracename]);
% %     set(htitle, 'Interpreter', 'none');
%     box off;
% end

% %% ============ STIMULATOR TRACE(S) ==================
% % TODO: plot multiple stimulator traces using FOR loop
% % TODO: get this working for flashes! (or make a qvFlash)
% if currentTrace.header.stimulator.stimulator.startButton && currentTrace.header.stimulator.stimulator.stimOnArray(1) == 1;
%     params = currentTrace.header.stimulator.stimulator.pulseParameters{:};
%     traceLength = currentTrace.header.stimulator.stimulator.traceLength;
%     if ~pulseJackerFlag
%         params = currentTrace.header.stimulator.stimulator.pulseParameters{:};
%     else
%         cp = currentTrace.header.pulseJacker.pulseJacker.currentPosition;
%         np = size(currentTrace.header.pulseJacker.pulseJacker.positions{1})
%         params = currentTrace.header.pulseJacker.pulseJacker.pulseDataMap{(cp-1)*np+1}(:);
%     end
%     pulseTrace = pulseTraceFromParameters(params, traceLength);
%     plotnum = plotnum + 1;
%     hsub = subplot(Nsub, 1, plotnum);
%     hplot = plot(timedata, pulseTrace);
%     set(hplot, 'LineWidth', 2, 'Color', 'r');
%     xlabel('Time (seconds)');
%     ylabel('Amplitude');
%     htitle = title(['Pulse: ' params.name]);
%     set(htitle, 'Interpreter', 'none');
%     box off;
% end

%% uicontrols -- sliders to scroll through traces
hscrollerbackwards = uicontrol('Style', 'pushbutton', 'String', '<<', ...
    'Units', 'normalized', ...
    'Position', [.92 .93 .04 .07], 'Callback', 'qvTrace(''scroll backwards'')');

hscrollerforwards = uicontrol('Style', 'pushbutton', 'String', '>>', ...
    'Units', 'normalized', ...
    'Position', [.96 .93 .04 .07], 'Callback', 'qvTrace(''scroll forwards'')');

% uicontrol -- pushbutton to select new file/directory
hselectnewfile = uicontrol('Style', 'pushbutton', 'String', 'New', ...
    'Units', 'normalized', ...
    'Position', [.92 .86 .08 .07], 'Callback', 'qvTrace(''select new file'')');

% % uicontrol -- pushbutton to print header to command line
% hheaderprint = uicontrol('Style', 'pushbutton', 'String', 'Header', ...
%     'Units', 'normalized', ...
%     'Position', [.92 .79 .08 .07], 'Callback', 'qvTrace(''header to command line'')');

%% something to show epoch